
// ===============================================================================================================
// -*- C++ -*-
//
// Common.cpp - Common code used by the application.
//
// Copyright (c) 2011 Guilherme R. Lampert
// guilherme.ronaldo.lampert@gmail.com
//
// This code is licenced under the MIT license.
//
// This software is provided "as is" without express or implied
// warranties. You may freely copy and compile this source into
// applications you distribute provided that the copyright text
// above is included in the resulting source code.
//
// ===============================================================================================================

#include <Common.hpp>
#include <malloc.h>

int CalcFPS(void)
{
	static int ret = 0;
	static float fps = 0.0f;
	static float lastTime = 0.0f;
	float currentTime = static_cast<float>((GetTickCount() * 0.001f));

	fps++;

	if ((currentTime - lastTime) > 1.0f)
    {
		lastTime = currentTime;
		ret = static_cast<int>(fps);
		fps = 0.0f;
	}

	return (ret);
}

float GetElapsedMilliseconds(void)
{
	// GetTickCount() is very fast and reasonably accurate. The down side however is that
	// if the system runs continuously for more than ~49 days the counter will reset to zero.
	static const DWORD baseTime = GetTickCount();
	return (static_cast<float>(GetTickCount() - baseTime));
}

float GetElapsedSeconds(void)
{
	return (GetElapsedMilliseconds() * 0.001f);
}

void SysErrorMessage(const char * format, ...)
{
	va_list argList;
	char charBuf[1024];

	va_start(argList, format);
	vsnprintf(charBuf, sizeof(charBuf), format, argList);
	va_end(argList);

	MessageBoxA(GetActiveWindow(), charBuf, "Error !", (MB_OK | MB_ICONERROR));
}

void SysWarningMessage(const char * format, ...)
{
	va_list argList;
	char charBuf[1024];

	va_start(argList, format);
	vsnprintf(charBuf, sizeof(charBuf), format, argList);
	va_end(argList);

	MessageBoxA(GetActiveWindow(), charBuf, "Warning !", (MB_OK | MB_ICONWARNING));
}

void SysOutputMessage(const char * caption, const char * format, ...)
{
	va_list argList;
	char charBuf[1024];

	va_start(argList, format);
	vsnprintf(charBuf, sizeof(charBuf), format, argList);
	va_end(argList);

	MessageBoxA(GetActiveWindow(), charBuf, caption, MB_OK);
}

void * MemAlloc(size_t numBytes, size_t alignment)
{
	return (_aligned_malloc(numBytes, alignment));
}

void MemFree(void * memory)
{
	if (memory != 0)
	{
		_aligned_free(memory);
	}
}

void * operator new (size_t numBytes)
{
	void * memory = MemAlloc(numBytes);

	if (!memory)
	{
		SysErrorMessage("FATAL ERROR! Out-of-memory");
		exit(EXIT_FAILURE);
	}

	return (memory);
}

void * operator new[] (size_t numBytes)
{
	void * memory = MemAlloc(numBytes);

	if (!memory)
	{
		SysErrorMessage("FATAL ERROR! Out-of-memory");
		exit(EXIT_FAILURE);
	}

	return (memory);
}

void operator delete (void * memory)
{
	MemFree(memory);
}

void operator delete[] (void * memory)
{
	MemFree(memory);
}